"""
数据整合模块
将向量数据整合到检索系统，添加元数据标签和结构化信息
"""

import logging

try:
    import pandas as pd
except ImportError:
    pd = None
import json
from typing import List, Dict, Any, Optional
from dataclasses import dataclass
import os

logger = logging.getLogger(__name__)


@dataclass
class StructuredData:
    """结构化数据"""

    content: str
    metadata: Dict[str, Any]
    tags: List[str]
    category: str


class DataIntegrator:
    """数据整合器"""

    def __init__(self, data_path: str = "./data/knowledge_base"):
        self.data_path = data_path
        self.structured_data = []
        self.metadata_index = {}

    def load_and_integrate_data(self) -> List[StructuredData]:
        """加载并整合所有数据"""
        try:
            # 1. 加载故障案例数据
            fault_cases = self._load_fault_cases()

            # 2. 加载经验数据
            experiences = self._load_experiences()

            # 3. 加载架构数据
            architectures = self._load_architectures()

            # 4. 整合所有数据
            all_data = fault_cases + experiences + architectures

            # 5. 构建元数据索引
            self._build_metadata_index(all_data)

            self.structured_data = all_data
            logger.debug(f"数据整合完成，共加载 {len(all_data)} 条结构化数据")

            return all_data

        except Exception as e:
            logger.error(f"数据整合失败: {e}")
            return []

    def _load_fault_cases(self) -> List[StructuredData]:
        """加载故障案例数据"""
        fault_cases = []
        csv_path = os.path.join(self.data_path, "fault_cases.csv")

        if not os.path.exists(csv_path):
            logger.warning(f"故障案例文件不存在: {csv_path}")
            return fault_cases

        if pd is None:
            logger.warning("pandas未安装，跳过CSV文件加载")
            return fault_cases

        try:
            df = pd.read_csv(csv_path)

            for _, row in df.iterrows():
                # 构建故障案例内容
                content = f"""
故障类型: {row.get('故障类型', '')}
故障现象: {row.get('故障现象', '')}
排查过程: {row.get('排查过程', '')}
根因分析: {row.get('根因分析', '')}
解决方案: {row.get('解决方案', '')}
预防措施: {row.get('预防措施', '')}
严重程度: {row.get('严重程度', '')}
影响范围: {row.get('影响范围', '')}
处理时间: {row.get('处理时间', '')}
                """.strip()

                # 构建元数据
                metadata = {
                    "case_id": row.get("案例ID", ""),
                    "fault_type": row.get("故障类型", ""),
                    "severity": row.get("严重程度", ""),
                    "impact_scope": row.get("影响范围", ""),
                    "processing_time": row.get("处理时间", ""),
                    "source": "fault_cases",
                }

                # 构建标签
                tags = [
                    row.get("故障类型", ""),
                    row.get("严重程度", ""),
                    row.get("影响范围", ""),
                    "故障案例",
                ]

                fault_cases.append(
                    StructuredData(
                        content=content,
                        metadata=metadata,
                        tags=[tag for tag in tags if tag],
                        category="fault_case",
                    )
                )

            logger.debug(f"加载故障案例数据: {len(fault_cases)} 条")

        except Exception as e:
            logger.error(f"加载故障案例数据失败: {e}")

        return fault_cases

    def _load_experiences(self) -> List[StructuredData]:
        """加载经验数据"""
        experiences = []
        csv_path = os.path.join(self.data_path, "experience.csv")

        if not os.path.exists(csv_path):
            logger.warning(f"经验数据文件不存在: {csv_path}")
            return experiences

        if pd is None:
            logger.warning("pandas未安装，跳过CSV文件加载")
            return experiences

        try:
            df = pd.read_csv(csv_path)

            for _, row in df.iterrows():
                # 构建经验内容
                content = f"""
问题场景: {row.get('问题场景', '')}
排查思路: {row.get('排查思路', '')}
关键技巧: {row.get('关键技巧', '')}
容易踩的坑: {row.get('容易踩的坑', '')}
应急处理: {row.get('应急处理', '')}
经验总结: {row.get('经验总结', '')}
适用级别: {row.get('适用级别', '')}
                """.strip()

                # 构建元数据
                metadata = {
                    "exp_id": row.get("经验ID", ""),
                    "problem_scenario": row.get("问题场景", ""),
                    "level": row.get("适用级别", ""),
                    "source": "experience",
                }

                # 构建标签
                tags = [row.get("问题场景", ""), row.get("适用级别", ""), "经验分享"]

                experiences.append(
                    StructuredData(
                        content=content,
                        metadata=metadata,
                        tags=[tag for tag in tags if tag],
                        category="experience",
                    )
                )

            logger.debug(f"加载经验数据: {len(experiences)} 条")

        except Exception as e:
            logger.error(f"加载经验数据失败: {e}")

        return experiences

    def _load_architectures(self) -> List[StructuredData]:
        """加载架构数据"""
        architectures = []
        csv_path = os.path.join(self.data_path, "architecture.csv")

        if not os.path.exists(csv_path):
            logger.warning(f"架构数据文件不存在: {csv_path}")
            return architectures

        if pd is None:
            logger.warning("pandas未安装，跳过CSV文件加载")
            return architectures

        try:
            df = pd.read_csv(csv_path)

            for _, row in df.iterrows():
                # 构建架构内容
                content = f"""
组件名称: {row.get('组件名称', '')}
服务类型: {row.get('服务类型', '')}
依赖服务: {row.get('依赖服务', '')}
关键功能: {row.get('关键功能', '')}
配置参数: {row.get('配置参数', '')}
监控指标: {row.get('监控指标', '')}
性能基准: {row.get('性能基准', '')}
故障影响: {row.get('故障影响', '')}
                """.strip()

                # 构建元数据
                metadata = {
                    "component_id": row.get("组件ID", ""),
                    "component_name": row.get("组件名称", ""),
                    "service_type": row.get("服务类型", ""),
                    "dependencies": row.get("依赖服务", ""),
                    "source": "architecture",
                }

                # 构建标签
                tags = [row.get("组件名称", ""), row.get("服务类型", ""), "架构组件"]

                architectures.append(
                    StructuredData(
                        content=content,
                        metadata=metadata,
                        tags=[tag for tag in tags if tag],
                        category="architecture",
                    )
                )

            logger.debug(f"加载架构数据: {len(architectures)} 条")

        except Exception as e:
            logger.error(f"加载架构数据失败: {e}")

        return architectures

    def _build_metadata_index(self, data: List[StructuredData]):
        """构建元数据索引"""
        self.metadata_index = {"by_category": {}, "by_tags": {}, "by_metadata": {}}

        for item in data:
            # 按类别索引
            category = item.category
            if category not in self.metadata_index["by_category"]:
                self.metadata_index["by_category"][category] = []
            self.metadata_index["by_category"][category].append(item)

            # 按标签索引
            for tag in item.tags:
                if tag not in self.metadata_index["by_tags"]:
                    self.metadata_index["by_tags"][tag] = []
                self.metadata_index["by_tags"][tag].append(item)

            # 按元数据索引
            for key, value in item.metadata.items():
                if key not in self.metadata_index["by_metadata"]:
                    self.metadata_index["by_metadata"][key] = {}
                if value not in self.metadata_index["by_metadata"][key]:
                    self.metadata_index["by_metadata"][key][value] = []
                self.metadata_index["by_metadata"][key][value].append(item)

    def get_data_by_category(self, category: str) -> List[StructuredData]:
        """根据类别获取数据"""
        return self.metadata_index.get("by_category", {}).get(category, [])

    def get_data_by_tag(self, tag: str) -> List[StructuredData]:
        """根据标签获取数据"""
        return self.metadata_index.get("by_tags", {}).get(tag, [])

    def get_data_by_metadata(self, key: str, value: str) -> List[StructuredData]:
        """根据元数据获取数据"""
        return self.metadata_index.get("by_metadata", {}).get(key, {}).get(value, [])

    def search_structured_data(
        self, query: str, category: str = None, tags: List[str] = None
    ) -> List[StructuredData]:
        """搜索结构化数据"""
        results = []

        # 如果指定了类别，先过滤
        if category:
            candidates = self.get_data_by_category(category)
        else:
            candidates = self.structured_data

        # 如果指定了标签，进一步过滤
        if tags:
            filtered_candidates = []
            for item in candidates:
                if any(tag in item.tags for tag in tags):
                    filtered_candidates.append(item)
            candidates = filtered_candidates

        # 简单的关键词匹配
        query_lower = query.lower()
        for item in candidates:
            if query_lower in item.content.lower():
                results.append(item)

        return results

    def get_metadata_summary(self) -> Dict[str, Any]:
        """获取元数据摘要"""
        summary = {
            "total_items": len(self.structured_data),
            "categories": {},
            "tags": {},
            "metadata_keys": set(),
        }

        for item in self.structured_data:
            # 统计类别
            category = item.category
            if category not in summary["categories"]:
                summary["categories"][category] = 0
            summary["categories"][category] += 1

            # 统计标签
            for tag in item.tags:
                if tag not in summary["tags"]:
                    summary["tags"][tag] = 0
                summary["tags"][tag] += 1

            # 统计元数据键
            for key in item.metadata.keys():
                summary["metadata_keys"].add(key)

        summary["metadata_keys"] = list(summary["metadata_keys"])

        return summary
